package com.wu.common.util.screen


/**
 * @author wkq
 *
 * @date 2021年08月20日 11:33
 *
 *@des
 *
 */

/**
 * What if you need pass some arguments for initialization jus like parameterized constructor?
 * Since we can't use constructor with the object keyword. So, we need to find some other way of
 * doing the same.
 *
 * We can archive this by using a SingletonHolder class.
 * Also, to make it thread-safe, we need to have a way of synchronized a double check locking principle.
 */
open class SingletonHolder<out T : Any, in A>(creator: (A) -> T) {
    private var creator: ((A) -> T)? = creator

    @Volatile
    private var instance: T? = null

    protected fun getInstanceInternal(arg: A): T {
        val checkInstance = instance
        if (checkInstance != null) return checkInstance
        return synchronized(this) {
            val checkInstanceAgain = instance
            if (checkInstanceAgain != null) checkInstanceAgain
            else {
                val created = creator!!(arg)
                instance = created
                creator = null
                created
            }
        }
    }

}